// OrderService.java
package com.estore.model;

import com.estore.service.ProductService;

import java.io.*;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;

/**
 * 订单服务类，负责订单相关的业务逻辑
 */
public class OrderService {

    // 存储所有订单
    private final Map<String, Order> orders = new ConcurrentHashMap<>();

    // 订单ID生成器
    private final AtomicLong orderIdGenerator = new AtomicLong(System.currentTimeMillis());

    private final ProductService productService;

    // 模拟当前用户ID

    public OrderService(ProductService productService) {
        this.productService = productService;
    }

    /**
     * 创建订单
     * @param userId 用户ID
     * @param cartItems 购物车商品映射
     * @return 创建的订单对象
     */
    public Order createOrder(String userId, Map<String, Integer> cartItems) {
        synchronized (this) { // 确保订单创建的原子性
            if (cartItems == null || cartItems.isEmpty()) {
                throw new IllegalArgumentException("购物车不能为空");
            }

            // 验证库存
            for (Map.Entry<String, Integer> entry : cartItems.entrySet()) {
                String productId = entry.getKey();
                int quantity = entry.getValue();

                Product product = productService.findProductById(productId);
                if (product == null) {
                    throw new IllegalArgumentException("商品ID %s 不存在".formatted(productId));
                }

                if (product.getStock() < quantity) {
                    throw new IllegalArgumentException("商品 %s 库存不足".formatted(product.getName()));
                }
            }

            // 计算总价
            double totalPrice = 0.0;
            for (Map.Entry<String, Integer> entry : cartItems.entrySet()) {
                String productId = entry.getKey();
                int quantity = entry.getValue();
                Product product = productService.findProductById(productId);
                totalPrice += product.getPrice() * quantity;
            }

            // 生成订单ID
            String orderId = "ORDER-%d".formatted(orderIdGenerator.incrementAndGet());

            // 创建订单
            Order order = new Order(orderId, userId, new HashMap<>(cartItems), totalPrice);
            orders.put(orderId, order);

            // 保存订单数据
            saveData();

            return order;
        }
    }


/**
 * 更新订单状态
 * @param orderId 订单ID
 * @param status 新的状态
 * @return 更新后的订单对象
 */
public Order updateOrderStatus(String orderId, Order.OrderStatus status) {
    Order order = orders.get(orderId);
    if (order == null) {
        return null;
    }

    // 验证订单状态流转的合法性
    if (!isValidStatusTransition(order.getStatus(), status)) {
        throw new IllegalArgumentException(
            String.format("无法从状态 '%s' 转换到状态 '%s'", order.getStatus(), status)
        );
    }

    // 如果订单状态变为已付款，需要减少库存
    if (status == Order.OrderStatus.PAID && order.getStatus() == Order.OrderStatus.PENDING_PAYMENT) {
        // 减少库存
        for (Map.Entry<String, Integer> entry : order.getItems().entrySet()) {
            String productId = entry.getKey();
            int quantity = entry.getValue();
            
            // 使用ProductService的reduceStock方法减少库存
            Product product = productService.findProductById(productId);
            if (product == null) {
                throw new RuntimeException("商品不存在: " + productId);
            }
            if (product.getStock() < quantity) {
                throw new RuntimeException("商品 '" + product.getName() + "' 库存不足，当前库存: " + product.getStock() + "，需要: " + quantity);
            }
            if (!productService.reduceStock(productId, quantity)) {
                throw new RuntimeException("减少商品库存失败: " + productId);
            }
        }
        System.out.printf("订单 %s 付款成功，已减少相应商品库存%n", orderId);
    }
    
    // 如果订单被取消，需要恢复库存（如果之前已经减少过）
    if (status == Order.OrderStatus.CANCELLED && order.getStatus() == Order.OrderStatus.PAID) {
        // 恢复库存
        for (Map.Entry<String, Integer> entry : order.getItems().entrySet()) {
            String productId = entry.getKey();
            int quantity = entry.getValue();
            
            Product product = productService.findProductById(productId);
            if (product != null) {
                product.setStock(product.getStock() + quantity);
                productService.saveData();
            }
        }
        System.out.printf("订单 %s 已取消，已恢复相应商品库存%n", orderId);
    }

    order.setStatus(status);
    saveData(); // 添加数据持久化调用
    return order;
}

/**
 * 验证订单状态流转是否合法
 * @param currentStatus 当前状态
 * @param newStatus 新状态
 * @return 是否为合法的状态转换
 */
private boolean isValidStatusTransition(Order.OrderStatus currentStatus, Order.OrderStatus newStatus) {
    // 相同状态不需要转换
    if (currentStatus == newStatus) {
        return false;
    }
    
    switch (currentStatus) {
        case PENDING_PAYMENT:
            // 待付款可以转换为：已付款、已取消
            return newStatus == Order.OrderStatus.PAID || newStatus == Order.OrderStatus.CANCELLED;
            
        case PAID:
            // 已付款可以转换为：配送中、已取消
            return newStatus == Order.OrderStatus.SHIPPING || newStatus == Order.OrderStatus.CANCELLED;
            
        case SHIPPING:
            // 配送中可以转换为：已完成
            return newStatus == Order.OrderStatus.COMPLETED;
            
        case COMPLETED:
            // 已完成是最终状态，不能转换
            return false;
            
        case CANCELLED:
            // 已取消是最终状态，不能转换
            return false;
            
        default:
            return false;
    }
}


    /**
     * 根据订单ID查找订单
     * @param orderId 订单ID
     * @return 订单对象，如果不存在返回null
     */
    public Order findOrderById(String orderId) {
        return orders.get(orderId);
    }

    /**
     * 获取用户所有订单
     * @return 订单列表
     */
    public List<Order> getAllOrders() {
        return new ArrayList<>(orders.values());
    }

    /**
     * 根据用户ID查找订单
     * @param userId 用户ID
     * @return 用户的订单列表
     */
    public List<Order> getOrdersByUserId(String userId) {
        List<Order> userOrders = new ArrayList<>();
        for (Order order : orders.values()) {
            if (order.getUserId().equals(userId)) {
                userOrders.add(order);
            }
        }
        return userOrders;
    }

    /**
     * 根据状态筛选订单
     * @param status 订单状态
     * @return 符合条件的订单列表
     */
    public List<Order> getOrdersByStatus(Order.OrderStatus status) {
        List<Order> result = new ArrayList<>();
        for (Order order : orders.values()) {
            if (order.getStatus() == status) {
                result.add(order);
            }
        }
        return result;
    }

    /**
     * 根据用户ID和状态筛选订单
     * @param userId 用户ID
     * @param status 订单状态
     * @return 符合条件的订单列表
     */
    public List<Order> getOrdersByUserIdAndStatus(String userId, Order.OrderStatus status) {
        List<Order> result = new ArrayList<>();
        for (Order order : orders.values()) {
            if (order.getUserId().equals(userId) && order.getStatus() == status) {
                result.add(order);
            }
        }
        return result;
    }

    /**
 * 从文件加载订单数据
 */
public synchronized void loadData(){
    try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("orders.dat"))) {
        Map<String, Order> loadedOrders = (Map<String, Order>) ois.readObject();
        orders.clear();
        orders.putAll(loadedOrders);

        // 更新订单ID生成器，确保新订单ID不会重复
        long maxId = loadedOrders.values().stream()
            .map(Order::getOrderId)
            .filter(id -> id.startsWith("ORDER-"))
            .map(id -> id.substring(6))
            .mapToLong(Long::parseLong)
            .max()
            .orElse(0L);

        if (maxId > 0) {
            orderIdGenerator.set(maxId);
        }

        System.out.println("订单数据已从 orders.dat 加载");
    } catch (FileNotFoundException e) {
        System.out.println("订单数据文件不存在，将创建新的数据文件");
    } catch (IOException | ClassNotFoundException e) {
        System.err.printf("加载订单数据时出错: %s%n", e.getMessage());
    }
}

/**
 * 保存订单数据到文件
 */

public void saveData() {
    try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("orders.dat"))) {
        oos.writeObject(orders);
        System.out.println("订单数据已保存到 orders.dat");
    } catch (IOException e) {
        System.err.printf("保存订单数据时出错: %s%n", e.getMessage());
        e.printStackTrace(); // 打印完整的堆栈跟踪以帮助调试
    }
}

/**
 * 检查并销毁过期订单（30分钟有效期）
 * @return 销毁的订单数量
 */
public synchronized int cleanupExpiredOrders() {
    int expiredCount = 0;
    LocalDateTime now = LocalDateTime.now();
    List<String> expiredOrderIds = new ArrayList<>();

    // 查找所有过期的待付款订单
    for (Order order : orders.values()) {
        if (order.getStatus() == Order.OrderStatus.PENDING_PAYMENT) {
            // 检查订单是否超过30分钟
            if (order.getCreateTime().plusMinutes(30).isBefore(now)) {
                expiredOrderIds.add(order.getOrderId());
            }
        }
    }

    // 销毁过期订单
    for (String orderId : expiredOrderIds) {
        Order expiredOrder = orders.remove(orderId);
        if (expiredOrder != null) {
            expiredCount++;
            System.out.printf("订单 %s 已过期并自动销毁（创建时间: %s）%n", 
                orderId, expiredOrder.getCreateTime());
        }
    }

    if (expiredCount > 0) {
        saveData(); // 保存更新后的订单数据
        System.out.printf("已清理 %d 个过期订单%n", expiredCount);
    }

    return expiredCount;
}

/**
 * 获取即将过期的订单列表（5分钟内过期）
 * @return 即将过期的订单列表
 */
public List<Order> getOrdersAboutToExpire() {
    List<Order> aboutToExpire = new ArrayList<>();
    LocalDateTime now = LocalDateTime.now();

    for (Order order : orders.values()) {
        if (order.getStatus() == Order.OrderStatus.PENDING_PAYMENT) {
            // 检查订单是否在5分钟内过期
            LocalDateTime expireTime = order.getCreateTime().plusMinutes(30);
            if (expireTime.minusMinutes(5).isBefore(now) && expireTime.isAfter(now)) {
                aboutToExpire.add(order);
            }
        }
    }

    return aboutToExpire;
}

/**
 * 检查指定订单是否已过期
 * @param orderId 订单ID
 * @return 是否已过期
 */
public boolean isOrderExpired(String orderId) {
    Order order = orders.get(orderId);
    if (order == null || order.getStatus() != Order.OrderStatus.PENDING_PAYMENT) {
        return false;
    }

    return order.getCreateTime().plusMinutes(30).isBefore(LocalDateTime.now());
}

/**
 * 获取订单剩余有效时间（分钟）
 * @param orderId 订单ID
 * @return 剩余分钟数，如果订单不存在或已过期返回-1
 */
public long getOrderRemainingMinutes(String orderId) {
    Order order = orders.get(orderId);
    if (order == null || order.getStatus() != Order.OrderStatus.PENDING_PAYMENT) {
        return -1;
    }

    LocalDateTime expireTime = order.getCreateTime().plusMinutes(30);
    if (expireTime.isBefore(LocalDateTime.now())) {
        return -1; // 已过期
    }

    return java.time.Duration.between(LocalDateTime.now(), expireTime).toMinutes();
}
}
